

#import "AppCache.h"

// MARK:公共字段
NSString * const kGlobalInfo    = @"cache_global_info";

// MARK:私有字段
static NSString * const kUserInfo   = @"cache_userInfo";    //!< 个人信息
static NSString * const kGuideInfo  = @"cache_guideInfo";   //!< 新功能引导

@implementation UserInfo
+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"account": @"account",
             @"userID": @"uid",
             @"jpushTags": @"jpush_tags",
             @"jpushAlias": @"jpush_alias",
             @"mobile": @"mobile",
             @"avatarURL": @"headpic",
             @"nickName": @"nick_name",
             @"userName": @"realname",
             // 业务
    };
}

+ (NSArray<NSString *> *)modelPropertyBlacklist {
    return @[];
}

- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
    return YES;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    return [self modelInitWithCoder:aDecoder];
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    return [self modelEncodeWithCoder:aCoder];
}
@end


@implementation CityModel
+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"cid" : @[@"id", @"area_id"],
             @"code" : @[@"code", @"citycode"],
             @"name" : @[@"name", @"cityname", @"city", @"area_name"],
             @"pinYin": @[@"pinyin", @"initials"]};
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super init];
    return [self modelInitWithCoder:aDecoder];
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
    [self modelEncodeWithCoder:aCoder];
}
@end


@interface AppCache ()
@property (nonatomic, strong) YYCache *cache;
@end

@implementation AppCache
- (instancetype)init {
    self = [super init];
    if (self) {
        _cache = [YYCache cacheWithName:kAppBundleID];
    }
    return self;
}

+ (instancetype)sharedInstance {
    static AppCache *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [self new];
    });
    return instance;
}

#pragma mark - setter/getter
- (BOOL)isLogin {
    return [self.cache containsObjectForKey:kUserInfo];
}

- (UserInfo *)userInfo {
    return (UserInfo *)[self.cache objectForKey:kUserInfo];
}

- (NSDictionary *)guideInfo {
    return (NSDictionary *)[self.cache objectForKey:kGuideInfo];
}


#pragma mark - method/public
- (void)onceCacheForKey:(NSString *)key success:(void (^)(id))success failure:(void (^)(void))failure hud:(BOOL)isHud {
    if ([self.cache.memoryCache containsObjectForKey:key]) {
        !success?:success([self.cache.memoryCache objectForKey:key]);
        return;
    }
    
    NSString *urlString;
    if ([key isEqualToString:kGlobalInfo])
        urlString = @"publics/globalparam";
    
    [_networker POST:urlString parameters:nil success:^(NSMResponseObject *responseObject) {
        [self.cache.memoryCache setObject:responseObject.data forKey:key];
        !success?:success(responseObject.data);
    } empty:^(NSMResponseObject *responseObject) {
        !failure?:failure();
    } failure:^(NSError *error) {
        !failure?:failure();
    } hud:isHud];
}

#pragma mark - UserInfo
- (void)updateUserInfo:(id)json reset:(BOOL)reset complete:(void (^)(void))complete {
    UserInfo *userInfo;
    if (reset) {
        // 重置
        userInfo = [UserInfo modelWithJSON:json];
    } else {
        NSMutableDictionary *info = @{}.mutableCopy;
        // 原始格式化数据(纠正key字段和模型一致)
        id oriFormatJson = self.userInfo.modelToJSONObject;
        [info addEntriesFromDictionary:oriFormatJson];
        // 加入新数据格式化
        UserInfo *newInfo = [UserInfo modelWithJSON:json];
        id newFormatJson = newInfo.modelToJSONObject;
        [info addEntriesFromDictionary:newFormatJson];
        
        userInfo = [UserInfo modelWithJSON:info];
    }
    
    if (!userInfo) return;
    [self.cache setObject:userInfo forKey:kUserInfo withBlock:^{
        dispatch_async_on_main_queue(^{
            !complete?:complete();
        });
    }];
}

- (void)clearUserInfo:(void (^)(void))complete {
    [self.cache removeObjectForKey:kUserInfo withBlock:^(NSString *key) {
        dispatch_async_on_main_queue(^{
            !complete?:complete();
        });
    }];
}

- (void)refreshUserInfo:(void (^)(id obj))completion hud:(BOOL)isHud {
    @nsm_weak(self)
    [_networker POST:@"mine/index" parameters:nil success:^(NSMResponseObject *responseObject) {
        @nsm_strong(self)
        id data = responseObject.data;
        [self updateUserInfo:data reset:NO complete:nil];
        !completion?:completion(data);
    } empty:^(NSMResponseObject *responseObject) {
        !completion?:completion(nil);
    } failure:^(NSError *error) {
        !completion?:completion(nil);
    } hud:isHud];
}

- (void)updateGuideInfo:(id)json complete:(void (^)(void))complete {
    NSMutableDictionary *info = @{}.mutableCopy;
    [info addEntriesFromDictionary:self.guideInfo];
    [info addEntriesFromDictionary:json];
    [self.cache setObject:info forKey:kGuideInfo withBlock:^{
        dispatch_async_on_main_queue(^{
            !complete?:complete();
        });
    }];
}

@end


